package com.easyctba.core.service.impl;

import cn.hutool.extra.spring.SpringUtil;
import com.easyctba.common.core.domain.R;
import com.easyctba.common.core.utils.MapstructUtils;
import com.easyctba.common.core.utils.StringUtils;
import com.easyctba.common.mybatis.core.page.TableDataInfo;
import com.easyctba.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.easyctba.core.domain.CtbaFiasClass;
import com.easyctba.core.domain.bo.FiasCategoryAddBo;
import com.easyctba.core.domain.vo.FiasCascaderVo;
import com.easyctba.core.domain.vo.FiasCategoryAndClassVo;
import com.easyctba.core.domain.vo.FiasTransferVo;
import com.easyctba.core.service.ICtbaFiasClassService;
import com.easyctba.core.service.ICtbaFiasService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.easyctba.core.domain.bo.CtbaFiasCategoryBo;
import com.easyctba.core.domain.vo.CtbaFiasCategoryVo;
import com.easyctba.core.domain.CtbaFiasCategory;
import com.easyctba.core.mapper.CtbaFiasCategoryMapper;
import com.easyctba.core.service.ICtbaFiasCategoryService;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.stream.Collectors;

/**
 * fias大类Service业务层处理
 *
 * @author Huang
 * @date 2024-03-22
 */
@RequiredArgsConstructor
@Service
public class CtbaFiasCategoryServiceImpl implements ICtbaFiasCategoryService {

    private final CtbaFiasCategoryMapper baseMapper;

    private final ICtbaFiasService fiasService;

    private final ICtbaFiasClassService fiasClassService;

    /**
     * 查询fias大类
     */
    @Override
    public CtbaFiasCategoryVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询fias大类列表
     */
    @Override
    public TableDataInfo<CtbaFiasCategoryVo> queryPageList(CtbaFiasCategoryBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<CtbaFiasCategory> lqw = buildQueryWrapper(bo);
        Page<CtbaFiasCategoryVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询fias大类列表
     */
    @Override
    public List<CtbaFiasCategoryVo> queryList(CtbaFiasCategoryBo bo) {
        LambdaQueryWrapper<CtbaFiasCategory> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<CtbaFiasCategory> buildQueryWrapper(CtbaFiasCategoryBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<CtbaFiasCategory> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getFiasId() != null, CtbaFiasCategory::getFiasId, bo.getFiasId());
        lqw.like(StringUtils.isNotBlank(bo.getCategoryName()), CtbaFiasCategory::getCategoryName, bo.getCategoryName());
        return lqw;
    }

    /**
     * 新增fias大类
     */
    @Override
    public Boolean insertByBo(CtbaFiasCategoryBo bo) {
        CtbaFiasCategory add = MapstructUtils.convert(bo, CtbaFiasCategory.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改fias大类
     */
    @Override
    public Boolean updateByBo(CtbaFiasCategoryBo bo) {
        CtbaFiasCategory update = MapstructUtils.convert(bo, CtbaFiasCategory.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(CtbaFiasCategory entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除fias大类
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public R<Void> addCategory(FiasCategoryAddBo bo) {
        //校验name是否重名
        Long id = bo.getId();
        String name = bo.getName();

        LambdaQueryWrapper<CtbaFiasCategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CtbaFiasCategory::getFiasId,id)
            .eq(CtbaFiasCategory::getCategoryName,name);
        CtbaFiasCategory ctbaFiasCategory = this.baseMapper.selectOne(wrapper);
        if (ctbaFiasCategory!=null){
            return R.fail("类型名称重复");
        }
        CtbaFiasCategory ctbaFiasCategory1 = new CtbaFiasCategory();
        ctbaFiasCategory1.setCategoryName(name);
        ctbaFiasCategory1.setFiasId(id);
        return this.baseMapper.insert(ctbaFiasCategory1)>0 ? R.ok() : R.fail("添加信息失败");
    }

    @Override
    public R<List<CtbaFiasCategory>> list(Long id) {
        LambdaQueryWrapper<CtbaFiasCategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CtbaFiasCategory::getFiasId,id);
        return  R.ok(this.baseMapper.selectList(wrapper));
    }

    @Override
    public R<Void> delete(Long id) {
       return this.baseMapper.deleteById(id)>0?R.ok():R.fail("删除失败");
    }

    /**
     * 查询FIAS分类详情
     * @param id FIAS ID
     * @return VO对象
     */
    @Override
    public R<List<FiasCategoryAndClassVo>> detail(Long id) {

        LambdaQueryWrapper<CtbaFiasCategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CtbaFiasCategory::getFiasId,id);
        var lists=new ArrayList<FiasCategoryAndClassVo>();
        for (CtbaFiasCategory ctbaFiasCategory : baseMapper.selectList(wrapper)) {
            //设置大类信息
            FiasCategoryAndClassVo vo = new FiasCategoryAndClassVo();
            vo.setId(ctbaFiasCategory.getId());
            vo.setFiasId(ctbaFiasCategory.getFiasId());
            vo.setCategoryName(ctbaFiasCategory.getCategoryName());
            List<CtbaFiasClass> classList=fiasClassService.selectByCategoryId(ctbaFiasCategory.getId());
            vo.setClassList(classList);
            vo.setClassSize((long) classList.size());
            lists.add(vo);
        }
        return R.ok(lists);
    }

    @Override
    public R<List<FiasCascaderVo>> cascader(Long id) {
        var wrapper = new LambdaQueryWrapper<CtbaFiasCategory>();
        wrapper.eq(CtbaFiasCategory::getFiasId,id);
        var lists=new ArrayList<FiasCascaderVo>();
        for (CtbaFiasCategory ctbaFiasCategory : baseMapper.selectList(wrapper)) {
            //设置大类信息
            var vo = new FiasCascaderVo();
            vo.setValue(ctbaFiasCategory.getId());
            vo.setLabel(ctbaFiasCategory.getCategoryName());
            //查询编码
            List<CtbaFiasClass> classList=fiasClassService.selectByCategoryId(ctbaFiasCategory.getId());
            List<FiasCascaderVo> children = classList.stream().map(result ->
                //格式： id num - name
                new FiasCascaderVo(result.getId(), result.getClassNum()+" - "+result.getClassName())
            ).toList();
            vo.setChildren(children);
            lists.add(vo);
        }
        return R.ok(lists);
    }

    @Override
    public R<List<FiasTransferVo>> transfer(Long id) {
        var wrapper = new LambdaQueryWrapper<CtbaFiasCategory>();
        wrapper.eq(CtbaFiasCategory::getFiasId,id);
        var lists=new ArrayList<FiasTransferVo>();
        for (CtbaFiasCategory ctbaFiasCategory : baseMapper.selectList(wrapper)){
            List<CtbaFiasClass> classList=fiasClassService.selectByCategoryId(ctbaFiasCategory.getId());
            for (CtbaFiasClass ctbaFiasClass : classList) {
                var vo = new FiasTransferVo();
                vo.setKey(ctbaFiasClass.getId());
                vo.setLabel(ctbaFiasClass.getClassNum()+" - "+ctbaFiasClass.getClassName());
                lists.add(vo);
            }
        }
        return R.ok(lists);
    }

    /**
     * 根据大类ids获取大类名
     * @param categoryIds 大类id集合
     * @return 大类名集合
     */
    @Override
    public List<String> getCategoryNames(List<Long> categoryIds) {
        LambdaQueryWrapper<CtbaFiasCategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(CtbaFiasCategory::getId,categoryIds);
        return baseMapper.selectList(wrapper)
            .stream().map(CtbaFiasCategory::getCategoryName).toList();
    }

    /**
     * 根据FIAS id获取大类id
     * @param id FIAS id
     * @return 大类信息
     */
    public List<Long> listCategoryByFiasId(Long id){
        LambdaQueryWrapper<CtbaFiasCategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(id!=null,CtbaFiasCategory::getFiasId,id);
        return baseMapper.selectList(wrapper)
            .stream().map(CtbaFiasCategory::getId).toList();
    }
}
